<template>
    <Category />

    <!-- table -->
    <el-card shadow="always" :body-style="{ padding: '20px' }">
        <template #header v-if="isAttrShow">
            <el-button type="primary" size="default" @click="openAbility" :icon="Plus">添加属性</el-button>
        </template>
        <!-- card body -->
        <el-table  border stripe :data="AttrButeList" v-if="isAttrShow"> 
            <el-table-column type="index" width="80" label="序号" align="center"/>
            <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column label="属性值名称列表" prop="attrValueList">
                <!-- 这里的row是表格数据，插槽默认接收 -->
                <template #default="{row}">
                    <el-tag type="success" size="small"  effect="dark" v-for="item in row.attrValueList" :key="item.id">{{item.valueName}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="200">
                <template #default="{row}">
                    <el-button type="warning" size="small" :icon="Edit" @click="attrEdit(row)">修改</el-button>
                    
                    <el-popconfirm title="你确定要删除吗?" @confirm="deleteAttr(row.id)">
                            <template #reference>
                                <el-button type="danger" size="small" :icon="Delete">删除</el-button>
                            </template>
                        </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>

        <!-- 添加属性列表 ，隐藏切换-->
        <div v-else>
            <el-form  label-width="80px" :inline="true" >
                <el-form-item label="属性名">
                    <el-input  placeholder="请输入属性名" v-model="newAttrData.attrName"></el-input>
                </el-form-item>
                <div>
                    <el-button type="primary" size="default" @click="addAttrName">添加属性名</el-button>
                    <el-button type="default" size="default" @click="cancelAbility">取消</el-button>
                </div>
            </el-form>
            <el-table  border stripe style="margin-top:20px" :data="newAttrData.attrValueList">
                <el-table-column type="index" label="序号" width="80"  align="center"/>
                <el-table-column label="属性值名称" prop="valueName">
                    <template #default="{row,$index}">
                        <el-input 
                        v-model="row.valueName"
                        v-if="row.isEdit"
                        ref="inputAttr"
                        @blur="LoseFocus(row,$index)"
                        @focus="SaveValueName(row)"
                        />
                        <span 
                        v-else
                        @click="toEdit(row)"
                        >{{row.valueName}}
                        </span>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="350">
                    <template #default="{$index}">
                        <!-- 气泡框，点击确认时触发删除 -->
                        <el-popconfirm title="你确定要删除吗?" @confirm="attrNameDelete($index)">
                            <template #reference>
                                <el-button type="danger" size="small"  icon="ele-Delete"></el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <div style="margin-top:20px">
                <el-button type="primary" size="default" @click="saveAttribute">保存</el-button>
                <el-button type="default" size="default" @click="cancelAbility">取消</el-button>
            </div>
        </div>
    </el-card>
    
</template>         

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from 'element-plus';


export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
import {watch,ref, nextTick} from 'vue'
import {Plus,Edit,Delete} from '@element-plus/icons-vue'
//引入pinia获取需要的数据
import useAttrStore from '@/stores/attr'
import { storeToRefs } from 'pinia';

//引入lodash
import cloneDeep from "lodash/cloneDeep";

//引入请求
import { deleteAttrButeList, requestAttrButeList, requestSaveAttrButeList, type AttrButeListItemType, type AttrButeListType, type attrValueListItemType } from '@/api/attr';

const AttrStore = useAttrStore()

//解构出需要的数据
const{category1Id,category2Id,category3Id} = storeToRefs(AttrStore)

//监听category3Id的变化。来发送请求
const AttrButeList = ref<AttrButeListType>([])

//封装请求函数，后面要用
const getAttrButeList=async()=>{
    try{
        //发送请求
        const re = await requestAttrButeList(category1Id.value as number,category2Id.value as number,category3Id.value as number)
        // console.log(re);
        AttrButeList.value = re
    }catch(e){
        ElMessage.error('获取失败')
    }
}

watch(category3Id,async()=>{
    //当category3Id没有值时，不进行请求
    if(!category3Id.value)return
    getAttrButeList()
},{immediate:true})



//添加属性和属性值的逻辑
//定义一个值来让添加属性和添加属性值显示隐藏
const isAttrShow = ref(true)

//定义提交表单时的数据
const newAttrData = ref<AttrButeListItemType>({
    //不需要id，后台自动生成
    attrName: '',
    categoryId: category3Id.value as number,//固定是category3Id
    categoryLevel: 3, //固定是3 
    attrValueList: []
})

//点击添加属性，进去属性值窗口
const openAbility =()=>{
    isAttrShow.value = false

    //每次点击添加属性时，清空属性数据
    newAttrData.value  ={
        attrName: '',
        categoryId: category3Id.value as number,
        categoryLevel: 3, 
        attrValueList: []
    }
}

//点击添加属性名时
const addAttrName =()=>{
    //点击是创建一个提交的属性
    const attrValue =ref({
        valueName :'', //写个空的占位
        attrId: newAttrData.value.id,   //这个值也是后台添加，给属性里面的一样，当属性被添加id，则加到属性名中
        //增加一个isedit
        isEdit:true
    })
    //把新值添加到提交表单中()
    newAttrData.value.attrValueList.push(attrValue.value)
    //添加一个框也要获取焦点
    nextTick(()=>{
        inputAttr.value.focus()
    })
}

// 点击修改逻辑时，需要填充数据
const attrEdit = (row:AttrButeListItemType)=>{
    //打开属性窗口
    isAttrShow.value = false
    
    //回填数据（不影响原数据，而且有深层次的对象，使用深拷贝）
    //添加查看和编辑模式，所以在克隆后需要加入一个布尔值
    // newAttrData.value = cloneDeep(row)
    //获取克隆数据
    const cloneDep = cloneDeep(row)
    //遍历添加一个开关
    cloneDep.attrValueList.forEach(item=>{
        //在api类型中添加可选
        item.isEdit = false
    })
    //把修改后的值给初始值
    newAttrData.value = cloneDep
}

//点击查看模式切换为编辑模式
//首先创建一个input，和input通过ref绑定
const inputAttr = ref()
//接收row
const toEdit = (row:attrValueListItemType)=>{
    row.isEdit = true
    //切换为编辑模式自动获取焦点
    //因为操作真实dom，所以通过nextTick()回调，等到dom更新完毕，再加载
    nextTick(()=>{
        inputAttr.value.focus()
    })
}

//当input获取焦点时，绑定一个事件
let oldAttrValueName = ''
const SaveValueName =(row:attrValueListItemType)=>{
    // 给旧值赋当前数据
    oldAttrValueName = row.valueName
    // console.log(oldAttrValueName,'111');
}
//当编辑模式表单失去焦点时
const LoseFocus =(row:attrValueListItemType,$index:number)=>{
    row.isEdit = false

    //判断，当输入框为空时,需要传入另一个参数，$index当前下标
    if(!row.valueName.trim()){
        if(!oldAttrValueName){
        newAttrData.value.attrValueList.splice($index,1)
        ElMessage.warning('数据不能为空')
        }else{
        row.valueName = oldAttrValueName
      }
    }

    //判断在修改状态下，输入的内容是不是和其他的重复
    //判断用户输入的是否有重复选项
    // 创建一个值作为后面重复的判断条件
    //some检查数组重复，如有有返回true
    const isRepeat = newAttrData.value.attrValueList.some((item)=>{
        //首先判断这个值所在的地址，是不是同一个对象内
        if(row === item){
            //如果等于直接return,不继续执行
            return
        }else{
            //返回
          return row.valueName === item.valueName
        }
    })

    // console.log(isRepeat,'11111');
    //当条件为true时，说明时重复的
    if(isRepeat){
        //如果是编辑修改，判断有无旧值
        if(oldAttrValueName){
            row.valueName = oldAttrValueName
        }else{
            newAttrData.value.attrValueList.splice($index,1)
        }
    }
    
    //逻辑结束，清空旧值
    oldAttrValueName = ''
 }

//删除添加的属性名逻辑
const attrNameDelete=($index:number)=>{
    newAttrData.value.attrValueList.splice($index,1)
}

//保存（发请求逻辑）
const saveAttribute = async()=>{
    //首先删除数据中的isEdit
    newAttrData.value.attrValueList.forEach(item=>{
        delete item.isEdit;
    })
    
    //判断提交的表单是不是空的
    if(newAttrData.value.attrValueList.length<= 0){
        ElMessage.error('表单不能为空提交')
        //终止
        return
    }
    //数据正常则发送请求
    try{
        await requestSaveAttrButeList(newAttrData.value)
        ElMessage.success('保存成功')
        //返回属性列表视图
        isAttrShow.value = true;
        // 重新发送请求
         getAttrButeList()
    }catch(e){
        ElMessage.error('保存失败')
    }
}

//点击删除属性
const deleteAttr=async(id:number)=>{
    try{
        await deleteAttrButeList(id)
        ElMessage.success('删除成功')
        // 重新发送请求
        getAttrButeList()
    }catch(e){
        ElMessage.error('删除失败')
    }
}

//点击取消，回到原来的属性列表
const cancelAbility =()=>{
    isAttrShow.value = true
}


</script>